"""日志工具

提供统一的日志记录功能。
"""

import os
import sys
import logging
from typing import Optional, Dict, Any
from pathlib import Path
import datetime


class ColoredFormatter(logging.Formatter):
    """彩色日志格式化器"""
    
    # ANSI颜色代码
    COLORS = {
        'DEBUG': '\033[36m',      # 青色
        'INFO': '\033[32m',       # 绿色
        'WARNING': '\033[33m',    # 黄色
        'ERROR': '\033[31m',      # 红色
        'CRITICAL': '\033[35m',   # 紫色
        'RESET': '\033[0m'        # 重置
    }
    
    def format(self, record):
        # 获取原始格式化的消息
        log_message = super().format(record)
        
        # 添加颜色
        color = self.COLORS.get(record.levelname, self.COLORS['RESET'])
        reset = self.COLORS['RESET']
        
        return f"{color}{log_message}{reset}"


class Logger:
    """日志管理器"""
    
    _instances: Dict[str, logging.Logger] = {}
    
    @classmethod
    def get_logger(
        cls,
        name: str = 'auto_video',
        level: str = 'INFO',
        log_file: Optional[str] = None,
        console_output: bool = True,
        colored_output: bool = True
    ) -> logging.Logger:
        """获取日志记录器
        
        Args:
            name: 日志记录器名称
            level: 日志级别
            log_file: 日志文件路径
            console_output: 是否输出到控制台
            colored_output: 是否使用彩色输出
            
        Returns:
            日志记录器实例
        """
        # 如果已存在相同名称的logger，直接返回
        if name in cls._instances:
            return cls._instances[name]
        
        # 创建新的logger
        logger = logging.getLogger(name)
        logger.setLevel(getattr(logging, level.upper()))
        
        # 避免重复添加处理器
        if logger.handlers:
            logger.handlers.clear()
        
        # 日志格式
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        
        # 控制台处理器
        if console_output:
            console_handler = logging.StreamHandler(sys.stdout)
            
            if colored_output and sys.stdout.isatty():
                # 使用彩色格式化器
                colored_formatter = ColoredFormatter(
                    '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S'
                )
                console_handler.setFormatter(colored_formatter)
            else:
                console_handler.setFormatter(formatter)
            
            logger.addHandler(console_handler)
        
        # 文件处理器
        if log_file:
            log_path = Path(log_file)
            log_path.parent.mkdir(parents=True, exist_ok=True)
            
            file_handler = logging.FileHandler(log_file, encoding='utf-8')
            file_handler.setFormatter(formatter)
            logger.addHandler(file_handler)
        
        # 缓存logger实例
        cls._instances[name] = logger
        
        return logger
    
    @classmethod
    def setup_default_logger(
        cls,
        log_dir: Optional[str] = None,
        level: str = 'INFO'
    ) -> logging.Logger:
        """设置默认日志记录器
        
        Args:
            log_dir: 日志目录
            level: 日志级别
            
        Returns:
            默认日志记录器
        """
        # 确定日志文件路径
        if log_dir:
            log_dir = Path(log_dir)
        else:
            log_dir = Path.cwd() / 'logs'
        
        log_dir.mkdir(parents=True, exist_ok=True)
        
        # 生成日志文件名
        timestamp = datetime.datetime.now().strftime('%Y%m%d')
        log_file = log_dir / f'auto_video_{timestamp}.log'
        
        return cls.get_logger(
            name='auto_video',
            level=level,
            log_file=str(log_file),
            console_output=True,
            colored_output=True
        )
    
    @classmethod
    def create_module_logger(
        cls,
        module_name: str,
        parent_logger: str = 'auto_video'
    ) -> logging.Logger:
        """创建模块日志记录器
        
        Args:
            module_name: 模块名称
            parent_logger: 父日志记录器名称
            
        Returns:
            模块日志记录器
        """
        logger_name = f"{parent_logger}.{module_name}"
        
        # 获取父logger的配置
        parent = logging.getLogger(parent_logger)
        
        # 创建子logger
        logger = logging.getLogger(logger_name)
        logger.setLevel(parent.level)
        
        # 子logger会继承父logger的处理器，所以不需要重复添加
        
        cls._instances[logger_name] = logger
        return logger


class ProgressLogger:
    """进度日志记录器"""
    
    def __init__(self, logger: logging.Logger, total: int, desc: str = ""):
        """初始化进度日志记录器
        
        Args:
            logger: 日志记录器
            total: 总数
            desc: 描述
        """
        self.logger = logger
        self.total = total
        self.desc = desc
        self.current = 0
        self.start_time = datetime.datetime.now()
    
    def update(self, n: int = 1, message: str = ""):
        """更新进度
        
        Args:
            n: 增加的数量
            message: 附加消息
        """
        self.current += n
        
        # 计算进度百分比
        percentage = (self.current / self.total) * 100 if self.total > 0 else 0
        
        # 计算耗时
        elapsed = datetime.datetime.now() - self.start_time
        elapsed_str = str(elapsed).split('.')[0]  # 去掉微秒
        
        # 估算剩余时间
        if self.current > 0:
            eta_seconds = (elapsed.total_seconds() / self.current) * (self.total - self.current)
            eta = datetime.timedelta(seconds=int(eta_seconds))
            eta_str = str(eta).split('.')[0]
        else:
            eta_str = "未知"
        
        # 构建进度消息
        progress_msg = f"{self.desc} [{self.current}/{self.total}] {percentage:.1f}%"
        progress_msg += f" | 耗时: {elapsed_str} | 预计剩余: {eta_str}"
        
        if message:
            progress_msg += f" | {message}"
        
        self.logger.info(progress_msg)
    
    def finish(self, message: str = "完成"):
        """完成进度
        
        Args:
            message: 完成消息
        """
        elapsed = datetime.datetime.now() - self.start_time
        elapsed_str = str(elapsed).split('.')[0]
        
        final_msg = f"{self.desc} {message} | 总耗时: {elapsed_str}"
        self.logger.info(final_msg)


class LogContext:
    """日志上下文管理器"""
    
    def __init__(self, logger: logging.Logger, operation: str, level: str = 'INFO'):
        """初始化日志上下文
        
        Args:
            logger: 日志记录器
            operation: 操作描述
            level: 日志级别
        """
        self.logger = logger
        self.operation = operation
        self.level = getattr(logging, level.upper())
        self.start_time = None
    
    def __enter__(self):
        self.start_time = datetime.datetime.now()
        self.logger.log(self.level, f"开始 {self.operation}")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        elapsed = datetime.datetime.now() - self.start_time
        elapsed_str = str(elapsed).split('.')[0]
        
        if exc_type is None:
            self.logger.log(self.level, f"完成 {self.operation} | 耗时: {elapsed_str}")
        else:
            self.logger.error(f"失败 {self.operation} | 耗时: {elapsed_str} | 错误: {exc_val}")
        
        return False  # 不抑制异常


def setup_logging(
    log_dir: Optional[str] = None,
    level: str = 'INFO',
    console: bool = True,
    file_logging: bool = True
) -> logging.Logger:
    """设置全局日志配置
    
    Args:
        log_dir: 日志目录
        level: 日志级别
        console: 是否输出到控制台
        file_logging: 是否记录到文件
        
    Returns:
        配置好的日志记录器
    """
    # 确定日志文件
    log_file = None
    if file_logging:
        if log_dir:
            log_dir = Path(log_dir)
        else:
            log_dir = Path.cwd() / 'logs'
        
        log_dir.mkdir(parents=True, exist_ok=True)
        timestamp = datetime.datetime.now().strftime('%Y%m%d')
        log_file = str(log_dir / f'auto_video_{timestamp}.log')
    
    return Logger.get_logger(
        name='auto_video',
        level=level,
        log_file=log_file,
        console_output=console,
        colored_output=True
    )


# 便捷函数
def get_logger(name: str = 'auto_video') -> logging.Logger:
    """获取日志记录器的便捷函数
    
    Args:
        name: 日志记录器名称
        
    Returns:
        日志记录器
    """
    return Logger.get_logger(name)


def log_function_call(logger: Optional[logging.Logger] = None):
    """函数调用日志装饰器
    
    Args:
        logger: 日志记录器
    """
    def decorator(func):
        def wrapper(*args, **kwargs):
            nonlocal logger
            if logger is None:
                logger = get_logger()
            
            func_name = func.__name__
            logger.debug(f"调用函数: {func_name}")
            
            try:
                result = func(*args, **kwargs)
                logger.debug(f"函数 {func_name} 执行成功")
                return result
            except Exception as e:
                logger.error(f"函数 {func_name} 执行失败: {e}")
                raise
        
        return wrapper
    return decorator